Project: Spatial Bros

Exploring Network-Constrained Spatial Point Analysis
network-constrained spatial point analysis
Author

Spatial Bros

Published

March 3, 2025

1 Network Constrained Spatial Point Pattern Analysis

1.1 Project Overview

Network constrained Spatial Point Patterns Analysis (NetSPAA) is a collection of spatial point patterns analysis methods special developed for analysing spatial point event occurs on or alongside network.

The spatial point event can be locations of childcare centre for example.

The network, on the other hand can be a road network for example.

More information with regards to data sources used for this project can be found at the proposal

1.2 Installing the R packages

In this project, x packages will be used

pacman::p_load(sp, sf, rgdal, spNetwork, tmap, readr, dplyr)

1.3 Data Import and Preparation

1.3.1 Melbourne City’s Road Network

Importing of shapefile, converting to EPSG of 7855 and converting Geometry Type to LINGSTRING.

road_network <- st_read("data/geospatial/Roads Network", layer = "road-corridors")
Reading layer `road-corridors' from data source 
  `C:\Users\Ming Rong\Desktop\IS415 Project\spatial-bros\data\geospatial\Roads Network' 
  using driver `ESRI Shapefile'
Simple feature collection with 4177 features and 9 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 144.897 ymin: -37.85066 xmax: 144.9913 ymax: -37.77545
Geodetic CRS:  WGS 84
road_network <- st_transform(road_network, crs = 7855)
road_network_lines <- st_boundary(road_network) %>% 
                     st_cast("LINESTRING")
Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

Warning in st_cast.MULTILINESTRING(X[[i]], ...): keeping first linestring only

1.3.2 Melbourne City’s Pedestrian Network

pedestrian_network <- st_read("data/geospatial/Pedestrian Network/pedestrian-network.geojson")
Reading layer `pedestrian-network' from data source 
  `C:\Users\Ming Rong\Desktop\IS415 Project\spatial-bros\data\geospatial\Pedestrian Network\pedestrian-network.geojson' 
  using driver `GeoJSON'
Simple feature collection with 85326 features and 3 fields
Geometry type: GEOMETRY
Dimension:     XY
Bounding box:  xmin: 144.8993 ymin: -37.85074 xmax: 144.9918 ymax: -37.77547
Geodetic CRS:  WGS 84
pedestrian_network <- st_transform(pedestrian_network, crs = 7855)

1.3.3 Melbourne City’s Tram Network

tram_network <- st_read("data/geospatial/Trams Network", layer = "PTV_METRO_TRAM_ROUTE")
Reading layer `PTV_METRO_TRAM_ROUTE' from data source 
  `C:\Users\Ming Rong\Desktop\IS415 Project\spatial-bros\data\geospatial\Trams Network' 
  using driver `ESRI Shapefile'
Simple feature collection with 82 features and 12 fields
Geometry type: LINESTRING
Dimension:     XY
Bounding box:  xmin: 144.878 ymin: -37.91422 xmax: 145.182 ymax: -37.67898
Geodetic CRS:  GDA2020
tram_network <- st_transform(tram_network, crs = 7855)

1.3.4 Localities

Localities file downloaded was entire Australia. Therefore, we need to filter to retrieve localities of Melbourne.

localities = st_read("data/geospatial/Localities", layer = "UCL_2021_AUST_GDA2020") 
Reading layer `UCL_2021_AUST_GDA2020' from data source 
  `C:\Users\Ming Rong\Desktop\IS415 Project\spatial-bros\data\geospatial\Localities' 
  using driver `ESRI Shapefile'
Simple feature collection with 1837 features and 12 fields (with 19 geometries empty)
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 96.81695 ymin: -43.7405 xmax: 167.998 ymax: -9.142163
Geodetic CRS:  GDA2020
melbourne_localities <- localities[localities$UCL_NAME21 == "Melbourne", ]
melbourne_localities <- st_transform(melbourne_localities, crs = 7855)

1.3.5 Melbourne City’s Local Government Areas

Local Government Areas file downloaded was entire Australia. Therefore, we need to filter to retrieve Local Government Areas of Melbourne.

local_government_areas = st_read("data/geospatial/Local Government Areas", layer = "LGA_2022_AUST_GDA2020")
Reading layer `LGA_2022_AUST_GDA2020' from data source 
  `C:\Users\Ming Rong\Desktop\IS415 Project\spatial-bros\data\geospatial\Local Government Areas' 
  using driver `ESRI Shapefile'
Simple feature collection with 566 features and 10 fields (with 19 geometries empty)
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 96.81695 ymin: -43.7405 xmax: 167.998 ymax: -9.142163
Geodetic CRS:  GDA2020
melbourne_local_government_areas = local_government_areas[local_government_areas$LGA_NAME22 == "Melbourne",]
melbourne_local_government_areas <- st_transform(melbourne_local_government_areas, crs = 7855)

1.3.6 Melbourne City’s Business Establishments Spatial Point

To retrieve only latest as of 2021 business establishments

business_est_sp <- st_read("data/geospatial/Business Establishments Spatial Point/business-establishments-with-address-and-industry-classification.geojson") %>% filter(census_year == "2021")
Reading layer `business-establishments-with-address-and-industry-classification' from data source `C:\Users\Ming Rong\Desktop\IS415 Project\spatial-bros\data\geospatial\Business Establishments Spatial Point\business-establishments-with-address-and-industry-classification.geojson' 
  using driver `GeoJSON'
replacing null geometries with empty geometries
Simple feature collection with 354556 features and 12 fields (with 4786 geometries empty)
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 144.8985 ymin: -37.85138 xmax: 144.9906 ymax: -37.77586
Geodetic CRS:  WGS 84
business_est_sp <- st_transform(business_est_sp, crs = 7855) 

1.3.7 Melbourne City’s Drinking Fountain Spatial Point

drinking_fountain_sp <- st_read("data/geospatial/Drinking Fountain Spatial Point", layer = "drinking-fountains")
Reading layer `drinking-fountains' from data source 
  `C:\Users\Ming Rong\Desktop\IS415 Project\spatial-bros\data\geospatial\Drinking Fountain Spatial Point' 
  using driver `ESRI Shapefile'
Simple feature collection with 302 features and 3 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 144.9159 ymin: -37.84521 xmax: 144.991 ymax: -37.77712
Geodetic CRS:  WGS 84
drinking_fountain_sp <- st_transform(drinking_fountain_sp, crs = 7855)

1.3.8 Melbourne City’s Landmarks Spatial Point

landmarks_sp <- st_read("data/geospatial/Landmarks Spatial Point", layer = "landmarks-and-places-of-interest-including-schools-theatres-health-services-spor")
Reading layer `landmarks-and-places-of-interest-including-schools-theatres-health-services-spor' from data source `C:\Users\Ming Rong\Desktop\IS415 Project\spatial-bros\data\geospatial\Landmarks Spatial Point' 
  using driver `ESRI Shapefile'
Simple feature collection with 242 features and 3 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 144.9082 ymin: -37.84852 xmax: 144.9894 ymax: -37.78127
Geodetic CRS:  WGS 84
landmarks_sp <- st_transform(landmarks_sp, crs = 7855)

1.3.9 Melbourne City’s Residential Dwellings Spatial Point

residential_dwelling_sp <- st_read("data/geospatial/Residential Dwellings Spatial Point/residential-dwellings.geojson")
Reading layer `residential-dwellings' from data source 
  `C:\Users\Ming Rong\Desktop\IS415 Project\spatial-bros\data\geospatial\Residential Dwellings Spatial Point\residential-dwellings.geojson' 
  using driver `GeoJSON'
replacing null geometries with empty geometries
Simple feature collection with 188160 features and 11 fields (with 2869 geometries empty)
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 144.905 ymin: -37.84798 xmax: 144.9908 ymax: -37.77583
Geodetic CRS:  WGS 84
residential_dwelling_sp <- st_transform(residential_dwelling_sp, crs = 7855)
st_crs(residential_dwelling_sp)
Coordinate Reference System:
  User input: EPSG:7855 
  wkt:
PROJCRS["GDA2020 / MGA zone 55",
    BASEGEOGCRS["GDA2020",
        DATUM["Geocentric Datum of Australia 2020",
            ELLIPSOID["GRS 1980",6378137,298.257222101,
                LENGTHUNIT["metre",1]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433]],
        ID["EPSG",7844]],
    CONVERSION["Map Grid of Australia zone 55",
        METHOD["Transverse Mercator",
            ID["EPSG",9807]],
        PARAMETER["Latitude of natural origin",0,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8801]],
        PARAMETER["Longitude of natural origin",147,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["Scale factor at natural origin",0.9996,
            SCALEUNIT["unity",1],
            ID["EPSG",8805]],
        PARAMETER["False easting",500000,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",10000000,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["(E)",east,
            ORDER[1],
            LENGTHUNIT["metre",1]],
        AXIS["(N)",north,
            ORDER[2],
            LENGTHUNIT["metre",1]],
    USAGE[
        SCOPE["Engineering survey, topographic mapping."],
        AREA["Australia - onshore and offshore between 144°E and 150°E."],
        BBOX[-50.89,144,-9.23,150.01]],
    ID["EPSG",7855]]

1.3.10 Melbourne City’s Childcare Centres Spatial Point

childcare_sp <- read_csv("data/geospatial/Childcare Centres Spatial Point/childcare-centres.csv")
Rows: 29 Columns: 6
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (3): name, contact_ph, url
dbl (3): ref, lat, lon

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

1.3.10.1 Creating a simple feature data frame from Childcare Centres Spatial Point listings

Upon research, it was found that EPSG: 4326 is wGS84 Geographic Coordinate System, therefore we have to convert it to Melbourne’s GDA2020 / MGA zone 55 – EPSG:7855 (https://parametricmonkey.com/2020/04/08/understanding-australias-coordinate-systems/)

childcare_sp_sf <- st_as_sf(childcare_sp, 
                       coords = c("lon", "lat"),
                       crs=4326) %>%
  st_transform(crs = 7855)

1.3.10.2 Converting to Spatial Point Data Frame

childcare_spdf <- as(childcare_sp_sf, "Spatial")
childcare_spdf
class       : SpatialPointsDataFrame 
features    : 29 
extent      : 316811.7, 322956.8, 5809281, 5816727  (xmin, xmax, ymin, ymax)
crs         : +proj=utm +zone=55 +south +ellps=GRS80 +units=m +no_defs 
variables   : 4
names       :    ref,                         name,   contact_ph,                          url 
min values  : 100083,     Alfred Child Care Centre, 03 8344 9621, http://emcc.org.au/yarra.php 
max values  : 717144, Yarra Park Children's Centre,    9820 2758,   http://www.wimblest.com.au 

1.3.11 Melbourne City’s Public Toilets Spatial Point

public_toilets_sp <- read_csv("data/geospatial/Public Toilets Spatial Point/public-toilets.csv")
Rows: 74 Columns: 8
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (6): name, female, male, wheelchair, operator, baby_facil
dbl (2): lat, lon

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

1.3.11.1 Creating a simple feature data frame from Public Toilets Spatial Point listings

Upon research, it was found that EPSG: 4326 is wGS84 Geographic Coordinate System, therefore we have to convert it to Melbourne’s GDA2020 / MGA zone 55 – EPSG:7855 (https://parametricmonkey.com/2020/04/08/understanding-australias-coordinate-systems/)

public_toilets_sp_sf <- st_as_sf(public_toilets_sp, 
                       coords = c("lon", "lat"),
                       crs=4326) %>%
  st_transform(crs = 7855)

1.3.11.2 Converting to Spatial Point Data Frame

public_toilets_spdf <- as(public_toilets_sp_sf, "Spatial")
public_toilets_spdf
class       : SpatialPointsDataFrame 
features    : 74 
extent      : 316969.7, 322790.1, 5809443, 5816753  (xmin, xmax, ymin, ymax)
crs         : +proj=utm +zone=55 +south +ellps=GRS80 +units=m +no_defs 
variables   : 6
names       :                                                        name, female, male, wheelchair,          operator, baby_facil 
min values  :      Public Toilet - Newmarket Reserve (26 Smithfield Road),     no,   no,         no, City of Melbourne,         no 
max values  : Public Toilet - Victoria Harbour, Shed 3 (North Wharf Road),    yes,  yes,        yes, City of Melbourne,        yes 

1.4 Visualising the Geospatial Data

1.4.1 Melbourne City’s road network with Childcare Centres

tmap_mode('view')
tmap mode set to interactive viewing
tm_basemap(server = "OpenStreetMap") +
  tm_shape(road_network_lines) +
  tm_lines() +
  tm_shape(childcare_spdf) + 
  tm_dots(size = 0.03, col="green")

1.4.2 Melbourne City’s road network with Drinking Fountain

 tmap_mode('view')
tmap mode set to interactive viewing
 tm_basemap(server = "OpenStreetMap") +
   tm_shape(road_network_lines) +
   tm_lines() +
   tm_shape(drinking_fountain_sp) +
   tm_dots(size = 0.03, col="green")